package tunnel

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"strconv"

	"internal-net-bridge-server/internal/models"
	"internal-net-bridge-server/internal/tunnel/protocols/common"
)

// ========================================
// 服务器管理模块
// ========================================
// 本文件负责隧道服务器的启动、监听和连接管理

// Start 启动隧道服务器
//
// 功能：
// 1. 监听隧道端口（用于隧道客户端连接）
// 2. 启动连接清理器（定期清理过期连接）
// 3. 接受隧道客户端连接
// 4. 为每个连接启动处理协程
//
// 参数：
//   - tunnelPort: 隧道服务器监听端口
//
// 返回：
//   - error: 启动错误
//
// 注意：
//   - 此函数会阻塞，直到服务器关闭
//   - 每个隧道连接都在独立的goroutine中处理
func (tm *TunnelManager) Start(tunnelPort int) error {
	tm.tunnelPort = tunnelPort

	// ⚠️ 旧的连接清理器已废弃（改用QUIC）
	// go tm.startConnectionCleaner()

	// 监听隧道端口
	tunnelListener, err := net.Listen("tcp", fmt.Sprintf(":%d", tunnelPort))
	if err != nil {
		log.Printf("❌ 隧道端口监听失败:")
		log.Printf("   ├─ 端口: %d", tunnelPort)
		log.Printf("   └─ 错误: %v", err)
		return err
	}
	defer tunnelListener.Close()

	log.Printf("✅ 隧道服务器启动成功:")
	log.Printf("   ├─ 监听端口: %d", tunnelPort)
	log.Printf("   └─ 等待隧道客户端连接...")

	// 创建TCP优化器
	tcpOptimizer := common.NewTCPOptimizer()
	log.Printf("✅ TCP优化器已启动: 拥塞控制=%s", tcpOptimizer.CongestionControl)

	// 接受隧道连接
	for {
		conn, err := tunnelListener.Accept()
		if err != nil {
			log.Printf("⚠️ 接受隧道连接失败: %v", err)
			continue
		}

		log.Printf("🔗 收到新的隧道连接:")
		log.Printf("   └─ 客户端地址: %s", conn.RemoteAddr().String())

		// 优化TCP连接（应用BBR/CUBIC拥塞控制）
		if err := tcpOptimizer.OptimizeConnection(conn); err != nil {
			log.Printf("⚠️ TCP连接优化失败: %v", err)
			// 继续处理连接，即使优化失败
		}

		// 处理隧道连接（每个连接独立处理）
		go tm.handleTunnelConnection(conn)
	}
}

// handleTunnelConnection 处理隧道客户端连接
//
// 工作流程：
// 1. 检测连接类型（HTTP/2或TCP）
// 2. 如果是HTTP/2，转发给HTTP/2处理器
// 3. 如果是TCP，使用原TCP协议处理：
//   - 设置读取超时（等待握手）
//   - 接收并验证握手信息（隧道ID、密钥）
//   - 从数据库加载隧道配置
//   - 验证密钥
//   - 更新隧道状态为已连接
//   - 启动公共端口监听（如果配置了）
//   - 启动域名路由（如果配置了）
//   - 发送握手响应
//   - 进入数据处理循环（调用handleTunnelData）
//   - 断开时清理资源
//
// 参数：
//   - conn: 隧道客户端的TCP连接
//
// 注意：
//   - 此函数在goroutine中运行
//   - 握手超时时间为30秒
//   - 数据处理超时时间为5分钟
func (tm *TunnelManager) handleTunnelConnection(conn net.Conn) {
	defer conn.Close()

	clientAddr := conn.RemoteAddr().String()
	log.Printf("⚠️ [DEPRECATED] 收到TCP隧道连接: %s", clientAddr)
	log.Printf("⚠️ TCP隧道协议已废弃，请使用QUIC连接（端口9443）")
}

// GetTunnelByID 通过ID获取隧道（实现TunnelManagerInterface）
func (tm *TunnelManager) GetTunnelByID(tunnelID string) (*models.Tunnel, bool) {
	tm.mutex.RLock()
	defer tm.mutex.RUnlock()
	tunnel, exists := tm.tunnels[tunnelID]
	return tunnel, exists
}

// HandleTunnelData 处理隧道数据（实现TunnelManagerInterface）
func (tm *TunnelManager) HandleTunnelData(tunnel *models.Tunnel, reader *bufio.Reader) error {
	return tm.handleTunnelData(tunnel, reader)
}

// StartPublicPortListener 启动公共端口监听器（实现TunnelManagerInterface）
func (tm *TunnelManager) StartPublicPortListener(tunnel *models.Tunnel) {
	// 🔥 使用新的协议监听器架构
	if tm.protocolFactory != nil {
		tm.startProtocolListener(tunnel)
	} else {
		// 向后兼容：如果协议工厂未初始化，使用旧方法
		log.Printf("⚠️ 协议工厂未初始化，使用旧版监听器")
		tm.startPublicPortListener(tunnel)
	}
}

// RegisterDomainMapping 注册域名映射（实现TunnelManagerInterface）
func (tm *TunnelManager) RegisterDomainMapping(tunnelID string, tunnel *models.Tunnel) error {
	if tm.domainRouter != nil && tm.tunnelService != nil {
		domain, err := tm.tunnelService.GetDomainByTunnelID(tunnelID)
		if err == nil && domain != "" && tunnel.PublicPort != "" {
			publicPortInt, err := strconv.Atoi(tunnel.PublicPort)
			if err == nil {
				tm.domainRouter.AddMapping(domain, publicPortInt)
				log.Printf("🌐 域名映射已注册: %s -> :%d", domain, publicPortInt)
				return nil
			}
			return err
		}
		return err
	}
	return nil
}

// RegisterTCPConnection 实现已在 manager.go 中定义
